package com.terrapages.wmsc4j.layer;

import org.apache.log4j.Logger;

import com.terrapages.wmsc4j.bean.BBox;
import com.terrapages.wmsc4j.bean.Pos;
import com.terrapages.wmsc4j.cache.Cache;
import com.terrapages.wmsc4j.layer.resolution.Resolution;
import com.terrapages.wmsc4j.layer.resolution.ResolutionSet;
import com.terrapages.wmsc4j.layer.tile.Tile;
import com.terrapages.wmsc4j.layer.tile.TileFormat;
import com.terrapages.wmsc4j.wms.WMSService;

/**
 * The basic implemtation of a {@link AbstractLiveLayer}
 * Does not metatile, simply puts the tile in cache from WMS service if it was not in cache.
 * @author mvivian
 */
public class WMSLayer extends AbstractLiveLayer {
	
	private static Logger log = Logger.getLogger(WMSLayer.class);
	
	/**
	 * Copies a existing {@link WMSLayer} using a new set of resolutions and a new coverage.
	 * @param layer existing AbstractLiveLayer
	 * @param resolutions new set of resolutions
	 * @param coverage new coverage area.
	 */
	protected WMSLayer(AbstractLiveLayer layer, ResolutionSet resolutions, BBox coverage) {
		super(layer, resolutions, coverage);
	}
	
	/**
	 * Contructs a {@link WMSLayer} 
	 * @param wmsService
	 * @param cache
	 * @param resolutions
	 * @param tilesize
	 * @param coverage
	 * @param origin
	 * @param title
	 */
	public WMSLayer(WMSService wmsService, Cache cache, ResolutionSet resolutions, TileFormat format, BBox coverage, Pos origin, String title) {
		super(wmsService,cache, resolutions, format, coverage, origin, title);
	}
	

	/**
	 * <p>Gets a layer that makes iteration useful and easy. The new layer is still essentially "this" Layer,
	 * but with a smaller set of resolutions and a smaller coverage. When you iterate a layer, it will give each tile
	 * in the entire coverage at every zoom level. This can be up to Several Billion Tiles!!
	 * By reducing the coverage and zoom levels you can focus your iterations on a specific sub-set of tiles.</p>
	 * 
	 * <p>When/If you do this, be aware of how you match tiles "zoom" with layer "resolution". 
	 * The new layer has less resolutions, so a resolution that used to correspond to a zoom 
	 * (based on index in resolution set) may now correspond to a different zoom. 
	 * Make use of layer.getResolution() and layer.getZoom(). These will match the zooms and resolutions up
	 * properly.</p>
	 * 
	 * @param coverage
	 * @param minZoom
	 * @param maxZoom
	 * @return A smaller sub-set Layer.
	 */
	public WMSLayer getSubCoverageLayer (BBox extent, int minZoom, int maxZoom)
	{
		final Resolution[] oldResolutions = getResolutions().toArray(new Resolution[this.getResolutions().size()]);
		ResolutionSet newResolutions = new ResolutionSet();
		for(int index = minZoom; index <= maxZoom; index++)
		{
			newResolutions.add(oldResolutions[index]);
		}

		WMSLayer retLayer = new WMSLayer(this,newResolutions,extent);
		return retLayer;
	}


	@Override
	/**
	 * Simply puts the tiles image into cache.
	 */
	protected void putInCacheAction(Tile tile) {
		log.debug("Tile " + tile.toString() + " image cached.");
		getCache().set(tile);
	}
}
